Palindrome Linked List
LeetCode 234 | Difficulty: Easyβ
EasyProblem Descriptionβ
Given the head of a singly linked list, return true if it is a palindrome or false otherwise.
Example 1:

Input: head = [1,2,2,1]
Output: true
Example 2:

Input: head = [1,2]
Output: false
Constraints:
- The number of nodes in the list is in the range `[1, 10^5]`.
- `0 <= Node.val <= 9`
Follow up: Could you do it in O(n) time and O(1) space?
Topics: Linked List, Two Pointers, Stack, Recursion
Approachβ
Stackβ
Use a stack (LIFO) to track elements that need future processing. Process elements when a "trigger" condition is met (e.g., finding a smaller/larger element). Monotonic stack maintains elements in sorted order for next greater/smaller element problems.
Matching brackets, next greater element, evaluating expressions, backtracking history.
Linked Listβ
Use pointer manipulation. Common techniques: dummy head node to simplify edge cases, fast/slow pointers for cycle detection and middle finding, prev/curr/next pattern for reversal.
In-place list manipulation, cycle detection, merging lists, finding the k-th node.
Solutionsβ
Solution 1: C# (Best: 176 ms)β
| Metric | Value |
|---|---|
| Runtime | 176 ms |
| Memory | N/A |
| Date | 2017-09-22 |
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public bool IsPalindrome(ListNode head) {
if(head==null || head.next == null) return true;
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
}
slow.next = Reverse(slow.next);
slow = slow.next;
while (slow != null)
{
if(head.val != slow.val) return false;
head = head.next;
slow = slow.next;
}
return true;
}
private static ListNode Reverse(ListNode head)
{
ListNode rev = null;
while (head != null)
{
ListNode temp = head;
head = head.next;
temp.next = rev;
rev = temp;
}
return rev;
}
}
π 1 more C# submission(s)
Submission (2022-02-02) β 459 ms, 52 MBβ
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public bool IsPalindrome(ListNode head) {
if(head==null || head.next == null) return true;
ListNode slow = head, fast = head;
while (fast != null && fast.next != null)
{
slow = slow.next;
fast = fast.next.next;
}
slow = Reverse(slow);
while (slow != null)
{
if(head.val != slow.val) return false;
head = head.next;
slow = slow.next;
}
return true;
}
private static ListNode Reverse(ListNode head)
{
ListNode rev = null;
while (head != null)
{
ListNode temp = head;
head = head.next;
temp.next = rev;
rev = temp;
}
return rev;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| Two Pointers | $O(n)$ | $O(1)$ |
| Stack | $O(n)$ | $O(n)$ |
| Linked List | $O(n)$ | $O(1)$ |
Interview Tipsβ
- Start by clarifying edge cases: empty input, single element, all duplicates.
- Draw the pointer changes before coding. A dummy head node simplifies edge cases.
- Think about what triggers a pop: is it finding a match, or finding a smaller/larger element?